package com.cpe.service.wechat;

import java.util.Date;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.cpe.data.domain.member.Member;
import com.cpe.repository.mapper.member.MemberMapper;
import com.wechat.api.WechatAPI;
import com.wechat.data.WechatReply;
import com.wechat.data.message.Message;
import com.wechat.data.message.receive.EventType;
import com.wechat.data.message.receive.MessageType;
import com.wechat.data.message.receive.ReceivedMessage;
import com.wechat.data.message.reply.PicArticleMessage;
import com.wechat.data.message.reply.TextMessage;
import com.wechat.data.message.reply.article.Articles;
import com.wechat.data.message.reply.article.Item;
import com.wechat.data.user.UserInfo;

import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Transactional
public class WechatService {

	@Resource
	private WechatAPI wechatAPI;

	@Resource
	private MemberMapper memberMapper;

	@Resource
	private WechatReply wechatReply;

	/**
	 * 消息处理
	 */
	public Message processMsg(ReceivedMessage msg) {
		switch (MessageType.valueOf(msg.getMsgType().toLowerCase())) {
		case event:
			return processEvent(msg);
		case text: {
			return processTextMsg(msg);
		}
		case image:

			break;
		case link:

			break;
		case location:

			break;
		case voice:

			break;
		default:
			break;
		}
		return null;
	}

	/**
	 * 回复文本消息
	 * 
	 * @param msg
	 * @return
	 */
	private Message processTextMsg(ReceivedMessage msg) {
		String keyword = msg.getContent();
		if (StringUtil.isBlank(keyword)) {
			return null;
		}

		if (keyword.contains("成绩")) {
			// 回复图文消息
			PicArticleMessage picArticleMessage = new PicArticleMessage();
			picArticleMessage.setFromUserName(msg.getToUserName());
			picArticleMessage.setToUserName(msg.getFromUserName());
			picArticleMessage.setCreateTime(new Date().getTime());
			picArticleMessage.setArticleCount(1);
			Articles articles = new Articles();
			Item item = new Item();
			item.setTitle(wechatReply.getChengji().getTitle());
			item.setDescription(wechatReply.getChengji().getDescription());
			item.setPicUrl(wechatReply.getChengji().getPicUrl());
			item.setUrl(wechatReply.getChengji().getUrl());
			articles.getItems().add(item);
			picArticleMessage.setArticles(articles);
			return picArticleMessage;
		} else {
			// 回复文本消息
			TextMessage textMessage = new TextMessage();
			textMessage.setFromUserName(msg.getToUserName());
			textMessage.setToUserName(msg.getFromUserName());
			textMessage.setMsgType(msg.getMsgType());
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setContent("你发送的是：" + msg.getContent());
			return textMessage;
		}
	}

	public static void main(String[] args) throws Exception {
		PicArticleMessage picArticleMessage = new PicArticleMessage();
		picArticleMessage.setFromUserName("gh_73b4164816a7");
		picArticleMessage.setToUserName("oalBnxC53p_rlY_f1dQ1LrBg-mEw");
		picArticleMessage.setCreateTime(new Date().getTime());
		picArticleMessage.setArticleCount(1);
		Articles articles = new Articles();
		Item item = new Item();
		item.setTitle("标题");
		item.setDescription("描述");
		item.setPicUrl("http://7xpjn9.com1.z0.glb.clouddn.com/cpe/187bfd3b7c7144f89aec5da1bbf187f1.jpg");
		item.setUrl(
				"http://mp.weixin.qq.com/s?__biz=MzIxMDA4MDE5Nw==&mid=404254325&idx=1&sn=c6c8a9f952dc74850556faa979f27673&scene=0&previewkey=mblPlrrKhfQWAB1zMO01f51iJUUG%2F7eLf7OA%2FVEtaJE%3D#wechat_redirect");
		articles.getItems().add(item);
		picArticleMessage.setArticles(articles);

		JAXBContext jaxbContext = JAXBContext.newInstance(PicArticleMessage.class);
		Marshaller marshaller = jaxbContext.createMarshaller();
		// 用来指定是否使用换行和缩排对已编组XML数据进行格式化的属性名称
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.marshal(picArticleMessage, System.out);
	}

	/**
	 * 处理事件类型的消息
	 * 
	 * @param msg
	 */
	private Message processEvent(ReceivedMessage msg) {
		String event = msg.getEvent().toLowerCase();
		switch (EventType.valueOf(event)) {
		case click:

			break;
		case subscribe: {
			// 发送欢迎词
			TextMessage textMessage = new TextMessage();
			textMessage.setFromUserName(msg.getToUserName());
			textMessage.setToUserName(msg.getFromUserName());
			textMessage.setMsgType(MessageType.text.getType());
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setContent(wechatReply.getSubscribe());

			// 用户关注事件
			String openid = msg.getFromUserName();
			// 获取用户基本信息
			UserInfo userInfo = wechatAPI.getUserInfo(openid);
			// 注册该用户到自己的平台里
			Member member = memberMapper.findByOpenid(openid);
			if (member == null) {
				member = new Member();
				member.setAddress(userInfo.address());
				member.setOpenid(openid);
				member.setName(openid);
				Assert.hasText(userInfo.getNickname());
				member.setNickName(userInfo.getNickname());
				member.setHeadImgurl(userInfo.getHeadimgurl());
				member.setBlacklistStatus(0);
				member.setCreateTime(new Date());
				try {
					log.debug("member = " + member);
					memberMapper.insert(member);
				} catch (Exception e) {
					// 主键重复，说明登录请求的完成时刻早于该异步事件，不用再注册
					log.error(e.getMessage(), e);
				}
			} else if (member.getSubscribeStatus() == 1) {
				member.setSubscribeStatus(0);
				member.setAddress(userInfo.address());
				member.setNickName(userInfo.getNickname());
				member.setHeadImgurl(userInfo.getHeadimgurl());
				memberMapper.updateById(member);
			}
			return textMessage;
		}
		case unsubscribe: {
			// 用户取消关注事件
			String openid = msg.getFromUserName();
			// 从自己的平台里标注该用户状态为取消关注
			Member member = memberMapper.findByOpenid(openid);
			if (member != null) {
				member.setSubscribeStatus(1);
				memberMapper.updateById(member);
			}
		}
			break;
		case view:
			System.out.println(msg.getEvent());
			break;
		default:
			break;
		}
		return null;
	}
}
